package com.xuxu.member.controller;

import com.baidu.aip.face.AipFace;
import com.xuxu.common.utils.R;
import com.xuxu.member.entity.UsersEntity;
import com.xuxu.member.service.impl.UsersServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @className: FaceController
 * @author: Maxuxu
 * @date: 2022/8/19 21:50
 * @description: 人脸识别的控制类
 */
@RestController
@Slf4j
public class FaceController {
    @Autowired
    private AipFace aipFace;

    @Autowired
    private UsersServiceImpl usersService;

    /**
     * 注册人脸
     * @param userName
     * @param faceBase
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "face/register",method = RequestMethod.POST)
    public R register(String userName, String faceBase) throws IOException {
        if(StringUtils.hasText(userName) && StringUtils.hasText(faceBase)) {
            // 文件上传的地址
            String filePath = "D:/test/faceimg";
            // 图片名称
            String fileName = userName + System.currentTimeMillis() + ".png";
            System.out.println(filePath + "\\" + fileName);
            File file = new File(filePath + "\\" + fileName);
            // 往数据库里插入一条用户数据
            UsersEntity user = new UsersEntity();
            user.setUname(userName);
            user.setUimg(filePath + "\\" + fileName);
            UsersEntity exitUser = usersService.selectUserByName(user);
            // 数据库没有此用户，代表当前的用户为新用户
            if(exitUser != null) {
                // return "0";
                return R.error("新用户，未登录").put("code", "0");
            }
            usersService.save(user);
            // 保存上传摄像头捕获的图片
            saveLocalImage(faceBase, file);
            // 向百度云人脸库插入一张人脸
            faceSetAddUser(aipFace,faceBase,userName);
        }
        // return "1";
        return R.ok().put("code", "1");

    }

    /**
     * 登录人脸
     * @param faceBase
     * @return
     */
    @RequestMapping(value = "face/login",method = RequestMethod.POST)
    public R login(@RequestBody Map<String,String> faceBase) {
        String faceData = faceBase.get("faceBase");
        // 进行人像数据对比
        JSONObject user = verifyUser(faceData, aipFace);
        Double num = (Double) user.get("score");
        if( num > 95) {
            // return "1";
            return R.ok("success").put("msg", user.get("user_id"));

        }else {
            // return "2";
            return R.error("error").put("msg", "0");
        }
    }

    /**
     * 人脸比对
     * @param imgBash64 照片转bash64格式
     * @return
     */
    public JSONObject verifyUser(String imgBash64,AipFace client) {
        HashMap<String, String> options = new HashMap<String, String>();
        JSONObject res = client.search(imgBash64, "BASE64", "user_01", options);
        JSONObject user = (JSONObject) res.getJSONObject("result").getJSONArray("user_list").get(0);
        System.out.println("人脸比对结果："+user.toString());
        // Double score = (Double) user.get("score");
        return user;
    }


    /**
     *
     * @Title: GenerateImage
     * @Description: 该方法的主要作用：// 对字节数组字符串进行Base64解码并生成图片,并上传至服务器
     * @param  @param imgStr
     * @param  @param imgFilePath
     * @param  @return 设定文件
     * @return  返回类型：boolean
     * @throws
     */
    public boolean saveLocalImage(String imgStr, File file) {
        // 图像数据为空
        if (imgStr == null) {
            System.out.println("图像数据为空");
            return false;
        }else {
            BASE64Decoder decoder = new BASE64Decoder();
            try {
                // Base64解码
                byte[] bytes = decoder.decodeBuffer(imgStr);
                for (int i = 0; i < bytes.length; ++i) {
                    if (bytes[i] < 0) {
                        bytes[i] += 256;
                    }
                }
                // 生成jpeg图片
                if(!file.exists()) {
                    file.getParentFile().mkdir();
                    OutputStream out = new FileOutputStream(file);
                    out.write(bytes);
                    out.flush();
                    out.close();
                    return true;
                }

            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }

    /**
     * @Title: facesetAddUser
     * @Description: 该方法的主要作用：人脸注册,给人脸库中注册一个人脸
     * @param  @param client 设定文件
     * @return  返回类型：void
     * @throws
     */
    public boolean faceSetAddUser(AipFace client, String faceBase, String username) {
        // 参数为数据库中注册的人脸
        HashMap<String, String> options = new HashMap<String, String>();
        options.put("user_info", "user's info");
        JSONObject res = client.addUser(faceBase, "BASE64", "user_01", username, options);
        System.out.println("注册的人脸识别的数据："+res.toString(2));
        return true;
    }
}
